package lowijs.XfDroid;

import static lowijs.XfDroid.XfDroidConstants.ARG_0;
import static lowijs.XfDroid.XfDroidConstants.DC_REASON;
import static lowijs.XfDroid.XfDroidConstants.EMPTY_STRING;
import static lowijs.XfDroid.XfDroidConstants.PASSWORD;
import static lowijs.XfDroid.XfDroidConstants.PREF_NEXT_CHECK;
import static lowijs.XfDroid.XfDroidConstants.STATE_PROGRESS_DIALOG;
import static lowijs.XfDroid.XfDroidConstants.UPDATE_URL;
import static lowijs.XfDroid.XfDroidConstants.USERNAME;
import static lowijs.XfDroid.XfDroidConstants.VERSION_NAME_PATTERN;
import static lowijs.XfDroid.XfDroidConstants.VERSION_PATTERN;
import static lowijs.XfDroid.XfDroidConstants.VERSION_URL;
import static lowijs.XfDroid.XfDroidConstants.XFIRE_VER_PREFIX;

import com.googlecode.xfdroid.R;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lowijs.XfireClient.XfireObserver;
import lowijs.XfireClient.event.EventManager;
import lowijs.XfireClient.event.MessageEvent;
import lowijs.XfireClient.event.XfireEvent;
import lowijs.XfireClient.packet.VersionPacket;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class Login extends Activity implements XfireObserver {
	private EditText etUsername = null;

	private EditText etPassword = null;

	private TextView etXfDroidVer = null;

	private TextView etXfireVer = null;

	private Button btLogin = null;

	private ProgressDialog pd = null;

	private String newVersion;

	public void onCreate(Bundle b) {
		super.onCreate(b);
		setContentView(R.layout.login2);
		ErrorHandler.install();

		FriendDBAdapter.getInstance(getBaseContext());
		etUsername = (EditText)findViewById(R.id.etUsername);
		etPassword = (EditText)findViewById(R.id.etPassword);
		etXfDroidVer = (TextView)findViewById(R.id.etXfDroidVer);
		etXfireVer = (TextView)findViewById(R.id.etXfireVer);
		btLogin = (Button)findViewById(R.id.btLogin);
		findViewById(R.id.tvNewVersion).setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				String url = UPDATE_URL.replace(ARG_0, newVersion);
				Uri uri = Uri.parse(url);
				Intent intent = new Intent(Intent.ACTION_VIEW, uri);
				startActivity(intent);
			}
		});
	
		OnClickListener loginListener = new OnClickListener() {
			public void onClick(View v) {
				showProgressDialog();
				loginToXfire(etUsername.getText().toString(),
						etPassword.getText().toString());
			}
		};
		btLogin.setOnClickListener(loginListener);
	
		Intent i = getIntent();

		if (i != null && i.getBooleanExtra(DC_REASON, false)) {
			toastHandler.sendEmptyMessage(R.string.logged_in_elsewhere);
		}

		Handler handler = new Handler() {
			@Override
			public void dispatchMessage(Message msg) {
				handleMessage(msg);
			}

			@Override
			public void handleMessage(Message msg) {
				findViewById(R.id.tvNewVersion).setVisibility(View.VISIBLE);
			}
		};

		new Thread(new VersionCheck(handler)).start();
	}

	class VersionCheck implements Runnable {
		private Handler handler;

		public VersionCheck(Handler handler) {
			this.handler = handler;
		}

		public void run() {
			try {
				SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(Login.this);
				long next = prefs.getLong(PREF_NEXT_CHECK, System.currentTimeMillis() - 86400000);

				if (next > System.currentTimeMillis()) {
					// Don't check again!
					return;
				}

				URL url = new URL(VERSION_URL);
				Pattern pattern = Pattern.compile(VERSION_PATTERN);
				Pattern pattern2 = Pattern.compile(VERSION_NAME_PATTERN);
				for (int i = 0; i < 5; i++) {
					try {
						BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
						try {
							int newestVersion = -1;
							newVersion = null;

							while (true) {
								String line = reader.readLine();
								if (line == null) break;
								Matcher matcher = pattern.matcher(line);

								if (matcher.find()) {
									newestVersion = Integer.parseInt(matcher.group(1));
								}

								matcher = pattern2.matcher(line);

								if (matcher.find()) {
									newVersion = matcher.group(1);
								}

								if (newVersion != null && newestVersion > 0) {
									PackageInfo info = getPackageManager().getPackageInfo("lowijs.XfDroid", PackageManager.GET_CONFIGURATIONS);

									if (newestVersion > info.versionCode) {
										handler.sendEmptyMessage(1);
									}

									break;
								}
							}
						} finally {
							reader.close();
						}

						break;
					} catch (Exception e) {
					}

					try {
						Thread.sleep(1000);
					} catch (Exception e) {
					}
				}

				Editor editor = prefs.edit();
				editor.putLong(PREF_NEXT_CHECK, System.currentTimeMillis() + 86400000);
				editor.commit();
			} catch (Exception e) {
			}
		}
	}
	
	public void onStart() {
		super.onStart();

		if (XfDroidService.isConnected()) {
			showFriends();
			return;
		}

		NotificationController.clearAll();
		EventManager.addObserver(this);
	
		SharedPreferences pr = getPreferences(MODE_PRIVATE);
		etUsername.setText(pr.getString(USERNAME, EMPTY_STRING));
		etPassword.setText(pr.getString(PASSWORD, EMPTY_STRING));

		String xfire = getString(R.string.xfire_ver);
		String xfdroid = getString(R.string.xfdroid_ver);
		String droidver = null;

		try {
			PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
			droidver = info.versionName;
		} catch (Exception e) {
			e.printStackTrace();
			droidver = e.getMessage();

			if (droidver == null) {
				droidver = getString(R.string.no_version);
			}
		}

		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
		xfdroid = xfdroid.replace(ARG_0, droidver);
		xfire = xfire.replace(ARG_0, XFIRE_VER_PREFIX + Integer.toString(VersionPacket.getVersion(prefs)));

		etXfDroidVer.setText(xfdroid);
		etXfireVer.setText(xfire);

		if (XfDroidService.isConnected()) {
			etUsername.setEnabled(false);
			etPassword.setEnabled(false);
			btLogin.setEnabled(false);
			btLogin.setVisibility(ImageView.INVISIBLE);

			new Thread() {
				public void run() {
					Handler handler = new Handler() {
						public void handleMessage(Message m) {
							showFriends();
						}
					};

					handler.sendEmptyMessage(0);
				}
			}.start();
		} else {
			etUsername.setEnabled(true);
			etPassword.setEnabled(true);
			btLogin.setVisibility(ImageView.VISIBLE);
		}
	}
	
	public void onStop() {
		super.onStop();
		EventManager.removeObserver(this);

		if (etUsername.getText().toString().length() > 0) {
			SharedPreferences.Editor pr = getPreferences(MODE_PRIVATE).edit();
			pr.putString(USERNAME, etUsername.getText().toString());
			pr.putString(PASSWORD, etPassword.getText().toString());
			pr.commit();
		}

		if (pd != null) {
			pd.dismiss();
		}
	}

	public void onSaveInstanceState(Bundle b) {
		b.putBoolean(STATE_PROGRESS_DIALOG, pd != null && pd.isShowing());
		super.onSaveInstanceState(b);
	}
	
	public void onRestoreInstanceState(Bundle b) {
		if (b.getBoolean(STATE_PROGRESS_DIALOG)) {
			showProgressDialog();
		}

		b.remove(STATE_PROGRESS_DIALOG);

		super.onRestoreInstanceState(b);
	}
	
	public void handleEvent(XfireEvent event) {
		switch (event.getEventType()) {
		case XfireEvent.XF_FLRECV:
		case XfireEvent.XF_ONLINE:
			showFriends();
			return;
		case XfireEvent.XF_DCREASON:
		case XfireEvent.XF_LOGINFAIL:
			if (pd != null) {
				pd.dismiss();
			}

			toastHandler.sendEmptyMessage(R.string.login_failed);
			return;
		case XfireEvent.XF_CONNECTIONFAIL:
			int id = R.string.connection_failed;

			if (event instanceof MessageEvent) {
				id = ((MessageEvent)event).getMessage();
			}

			if (pd != null) {
				pd.dismiss();
			}

			toastHandler.sendEmptyMessage(id);

			return;
		}
	}

	private void loginToXfire(String username, String password) {
		Intent i = new Intent(this, XfDroidService.class);
		i.putExtra(USERNAME, username);
		i.putExtra(PASSWORD, password);
		startService(i);
	}
	
	private void showProgressDialog() {
		pd = new ProgressDialog(this);
		pd.setTitle(R.string.please_wait);		
		pd.setMessage(getString(R.string.logging_in));
		pd.setCancelable(false);
		pd.show();
	}

	private Handler toastHandler = new Handler() {
		public void handleMessage(Message m) {
			Toast t = Toast.makeText(getBaseContext(), m.what, 2);
			t.show();
		}
	};

	private void showFriends() {
		if (pd != null) {
			pd.dismiss();
		}

		startActivity(new Intent(this, Friendslist.class));
		finish();
	}
}
